#include <antlr3.h>
#include "PythonLexer.h"
#include "PythonTokenSource.h"

static void insertImaginaryIndentDedentTokens(pANTLR3_TOKEN_SOURCE tokenSource) {
	pANTLR3_LEXER lexer = (pANTLR3_LEXER)(tokenSource->super);
	pANTLR3_COMMON_TOKEN tok = NULL;
	int cpos, lastIndent;
	SPLexContext* lexCtx = (SPLexContext*)(lexer->rec->state->userp);
#define NEXTTOK do { \
		lexCtx->startPos = lexer->getCharPositionInLine(lexer); \
		tok = lexCtx->oldNextToken(tokenSource);	\
	}while(tok == NULL || tok->channel != 0);

	NEXTTOK;
	pushSPToken(lexCtx, tok);
	if (tok->getType(tok) != NEWLINE) {
		return;
	}
	NEXTTOK;
	cpos = tok->getCharPositionInLine(tok);
	if (tok->getType(tok) == ANTLR3_TOKEN_EOF)
		cpos = -1;
	else if (tok->getType(tok) == LEADING_WS)
		cpos = tok->getText(tok)->len;
	lastIndent = lexCtx->indentStack[lexCtx->indentStackSize - 1];
	if (cpos > lastIndent) {
		pANTLR3_COMMON_TOKEN indent = lexer->rec->state->tokFactory->newToken(lexer->rec->state->tokFactory);
		indent->type = INDENT;
		indent->charPosition = tok->charPosition;
		indent->line = tok->line;

		pushSPIndent(lexCtx, cpos);
		pushSPToken(lexCtx, indent);
	}
	else if (cpos < lastIndent) {
		int prevIndex = spFindPreviousIndent(lexCtx, cpos);
		while (lexCtx->indentStackSize > prevIndex + 1) {
			pANTLR3_COMMON_TOKEN dedent = lexer->rec->state->tokFactory->newToken(lexer->rec->state->tokFactory);
			dedent->type = DEDENT;
			dedent->charPosition = tok->charPosition;
			dedent->line = tok->line;
			pushSPToken(lexCtx, dedent);
			popSPIndent(lexCtx);
		}
	}
	if (tok->type != LEADING_WS)
		pushSPToken(lexCtx, tok);
#undef NEXTTOK
}

pANTLR3_COMMON_TOKEN spNextToken(pANTLR3_TOKEN_SOURCE tokenSoure) {
	pANTLR3_LEXER lexer = (pANTLR3_LEXER)(tokenSoure->super);

	SPLexContext* lexCtx = (SPLexContext*)(lexer->rec->state->userp);
	pANTLR3_COMMON_TOKEN tok = popSPToken(lexCtx);
	if (tok)
		return tok;
	insertImaginaryIndentDedentTokens(tokenSoure);
	return spNextToken(tokenSoure);
}

